﻿using Simple.Common.Authentication;
using Simple.Services.System;

namespace Simple.Services
{
    public class ClassesService : BusinessBaseService
    {
        private readonly SimpleDbContext _context;

        public ClassesService(SimpleDbContext context,
            ISimpleService services) : base(services)
        {
            _context = context;
        }

        public async Task<List<ClassesModel>> GetByTeacher()
        {
            var result = new List<ClassesModel>();
            var userId = _currentUser?.FindClaimValue(SimpleClaimTypes.UserId);
            if (userId == null)
            {
                return result;
            }
            var lstClass = (await OrganizationFilter(_context.Set<SysClasses>().AsQueryable())).Where(p => p.TeacherIds.Contains(userId) && p.IsArchived == false).ToList();
            return MapperHelper.Map<List<ClassesModel>>(lstClass);
        }

        public async Task<List<ClassesModel>> GetAsync(bool? isArchived)
        {
            var lstClasses = await OrganizationFilter(_context.Set<SysClasses>().AsQueryable());
            if (isArchived.HasValue)
            {
                lstClasses = lstClasses.Where(p => p.IsArchived == isArchived);
            }
            return MapperHelper.Map<List<ClassesModel>>(await lstClasses.ToListAsync());
        }

        public async Task<PageResultModel<ClassesModel>> GetPageAsync(ClassesPageInputModel input)
        {
            var result = new PageResultModel<ClassesModel>();
            var query = await OrganizationFilter(_context.Set<SysClasses>().AsQueryable());

            // 根据条件查询
            if (!string.IsNullOrEmpty(input.ClassName))
            {
                query = query.Where(u => u.Name.Contains(input.ClassName));
            }
            if (input.IsArchived.HasValue)
            {
                query = query.Where(u => u.IsArchived == input.IsArchived);
            }
            if (input.ArchiveTime.HasValue)
            {
                query = query.Where(u => u.ArchiveTime.Value.Year == input.ArchiveTime.Value.Year && u.ArchiveTime.Value.Month == input.ArchiveTime.Value.Month);
            }


            // 获取总数量
            result.TotalRows = await query.CountAsync();

            // 分页查询
            query = query.OrderBy(u => u.CreatedTime).Page(input.PageNo, input.PageSize);
            var lstClasses = await query.ToListAsync();
            var lstClassDto = MapperHelper.Map<List<ClassesModel>>(lstClasses);
            if (lstClassDto != null)
            {
                var lstChild = await _context.Set<Childrens>().ToListAsync();
                var lstUser = await _context.Set<SysUser>().ToListAsync();
                var lstTeacherId = new List<string>();
                var lstNurseId = new List<string>();
                foreach (var classes in lstClassDto)
                {
                    classes.ChildCount = lstChild.Where(p => p.ClassesId == classes.Id.ToString()).ToList().Count();
                    if (classes.TeacherIds != null)
                    {
                        lstTeacherId = classes.TeacherIds.Split(",").ToList();
                        var lstTeacher = lstUser.Where(p => lstTeacherId.Contains(p.Id.ToString())).Select(p => p.Name);
                        classes.TeacherName = string.Join(",", lstTeacher);
                    }
                    if (classes.NurseIds != null)
                    {
                        lstNurseId = classes.NurseIds.Split(",").ToList();
                        var lstNurse = lstUser.Where(p => lstNurseId.Contains(p.Id.ToString())).Select(p => p.Name);
                        classes.NurseName = string.Join(",", lstNurse);
                    }
                }
            }

            result.Rows = lstClassDto;

            result.SetPage(input);
            result.CountTotalPage();

            return result;
        }

        public async Task<int> AddAsync(ClassesModel model)
        {
            if (await _context.Set<SysClasses>().AnyAsync(u => u.Name == model.Name && u.GardenId == model.GardenId))
            {
                throw AppResultException.Status409Conflict("园区存在相同班级");
            }

            var classes = MapperHelper.Map<SysClasses>(model);

            await _context.AddAsync(classes);
            return await _context.SaveChangesAsync();
        }

        public async Task<int> UpdateAsync(ClassesModel model)
        {
            if (await _context.Set<SysClasses>().AnyAsync(u => u.Id != model.Id && u.Name == model.Name && u.GardenId == model.GardenId))
            {
                throw AppResultException.Status409Conflict("园区存在相同班级名称");
            }

            var classes = await _context.Set<SysClasses>()
                .Where(u => model.Id == u.Id)
                .FirstOrDefaultAsync();

            if (classes == null)
            {
                throw AppResultException.Status404NotFound("找不到班级，更新失败");
            }

            MapperHelper.Map(model, classes);

            _context.Update(classes);
            int ret = await _context.SaveChangesAsync();

            if (ret == 0)
            {
                throw AppResultException.Status200OK("更新记录数为0");
            }

            return ret;
        }

        public async Task<int> DeleteAsync(IEnumerable<Guid> ids)
        {
            var lstId = ids.Select(p => p.ToString()).ToList();
            if (await _context.Set<Childrens>().AnyAsync(p => lstId.Contains(p.ClassesId)))
            {
                throw AppResultException.Status409Conflict("删除失败，删除的班级中还有学生");
            }
            var lstClasses = await _context.Set<SysClasses>()
                .Where(u => ids.Contains(u.Id))
                .ToListAsync();

            _context.RemoveRange(lstClasses);
            return await _context.SaveChangesAsync();
        }

        /// <summary>
        /// 花名册
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResultModel<ChildrenModel>> Roster(RosterPageInputModel input)
        {
            var result = new PageResultModel<ChildrenModel>();
            var query = _context.Set<Childrens>().AsQueryable().Where(p => p.ClassesId == input.ClassId);

            // 获取总数量
            result.TotalRows = await query.CountAsync();

            // 分页查询
            query = query.OrderBy(u => u.CreatedTime).Page(input.PageNo, input.PageSize);
            var lstChild = await query.ToListAsync();
            var lstChildDto = MapperHelper.Map<List<ChildrenModel>>(lstChild);
            if (lstChildDto != null)
            {
                var classes = await _context.Set<SysClasses>().FirstOrDefaultAsync(p => p.Id.ToString() == input.ClassId);
                if (classes != null)
                {
                    foreach (var child in lstChildDto)
                    {
                        child.ClassName = classes.Name;
                    }
                }
            }

            result.Rows = lstChildDto;

            result.SetPage(input);
            result.CountTotalPage();

            return result;
        }

        /// <summary>
        /// 班级归档
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<int> ArchiveAsync(IEnumerable<Guid> ids)
        {
            var lstClasses = await _context.Set<SysClasses>()
                .Where(u => ids.Contains(u.Id))
                .ToListAsync();
            var archiveTime = DateTime.Now;
            foreach (var classes in lstClasses)
            {
                classes.ArchiveTime = archiveTime;
                classes.IsArchived = true;
            }
            _context.UpdateRange(lstClasses);

            // 幼儿毕业
            var lstChild = await _context.Set<Childrens>().ToListAsync();
            var lstChangeChild = new List<Childrens>();
            var gradDay = DateTime.Now;
            foreach (var classes in lstClasses)
            {
                var lstClassChild = lstChild.Where(p => p.ClassesId == classes.Id.ToString()).ToList();
                if (lstClassChild.Any())
                {
                    foreach (var child in lstClassChild)
                    {
                        child.ChildState = EnumChildState.Grad;
                        child.GradDay = gradDay;
                    }
                    lstChangeChild.AddRange(lstClassChild);
                }
            }
            _context.UpdateRange(lstChangeChild);
            return await _context.SaveChangesAsync();
        }

        /// <summary>
        /// 归档信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResultModel<ClassesModel>> Archiveinfo(ClassesPageInputModel input)
        {
            var result = new PageResultModel<ClassesModel>();
            var query = _context.Set<SysClasses>().AsQueryable();
            query = query.Where(p => p.IsArchived == true);
            // 根据条件查询
            if (!string.IsNullOrEmpty(input.ClassName))
            {
                query = query.Where(u => u.Name.Contains(input.ClassName));
            }
            if (input.ArchiveTime.HasValue)
            {
                query = query.Where(u => u.ArchiveTime.Value.Year == input.ArchiveTime.Value.Year && u.ArchiveTime.Value.Month == input.ArchiveTime.Value.Month);
            }

            // 获取总数量
            result.TotalRows = await query.CountAsync();

            // 分页查询
            query = query.OrderBy(u => u.CreatedTime).Page(input.PageNo, input.PageSize);
            var lstClasses = await query.ToListAsync();
            var lstClassDto = MapperHelper.Map<List<ClassesModel>>(lstClasses);
            if (lstClassDto != null)
            {
                var lstUser = await _context.Set<SysUser>().ToListAsync();
                var lstTeacherId = new List<string>();
                var lstNurseId = new List<string>();
                foreach (var classes in lstClassDto)
                {
                    if (classes.TeacherIds != null)
                    {
                        lstTeacherId = classes.TeacherIds.Split(",").ToList();
                        var lstTeacher = lstUser.Where(p => lstTeacherId.Contains(p.Id.ToString())).Select(p => p.Name);
                        classes.TeacherName = string.Join(",", lstTeacher);
                    }
                    if (classes.NurseIds != null)
                    {
                        lstNurseId = classes.NurseIds.Split(",").ToList();
                        var lstNurse = lstUser.Where(p => lstNurseId.Contains(p.Id.ToString())).Select(p => p.Name);
                        classes.NurseName = string.Join(",", lstNurse);
                    }
                }
            }

            result.Rows = lstClassDto;

            result.SetPage(input);
            result.CountTotalPage();

            return result;
        }
    }
}
